#ifndef TYPE_H
#define TYPE_H
#include "interpreter.h"
class Type {
public:
    /* given a parent type, get a matching derived type and make one if necessary.
     * identifier should be registered with the shared string table. */
    static ValueType *TypeGetMatching(Interpreter *pc, ParseState *parser,
                               ValueType *parentType, BaseType base, int arraySize,
                               const char *identifier, int allowDuplicates);

    /* stack space used by a Value */
    static int TypeStackSizeValue(Value *val);

    /* memory used by a Value */
    static int TypeSizeValue(Value *val, int compact);

    /* memory used by a variable given its type and array size */
    static int TypeSize(ValueType *typ, int arraySize, int compact);

    /* initialize the type system */
    static void TypeInit(Interpreter *pc);

    static void TypeCleanup(Interpreter *pc);

    /* create a system struct which has no user-visible members */
    static ValueType *TypeCreateOpaqueStruct(Interpreter *pc, ParseState *parser,
                                      const char *structName, int size);

    /* parse a type - just the basic type */
    static int TypeParseFront(ParseState *parser, ValueType **typ,
                       int *isStatic);

    /* parse a type - the part which is repeated with each
        identifier in a declaration list */
    static void TypeParseIdentPart(Interpreter *pc, ParseState *parser, ValueType *basicTyp,
                            ValueType **typ, char **identifier);

    /* parse a type - a complete declaration including identifier */
    static void TypeParse(Interpreter *pc, ParseState *parser, ValueType **typ,
                   char **identifier, int *isStatic);

    /* check if a type has been fully defined - otherwise it's
        just a forward declaration */
    static int TypeIsForwardDeclared(ParseState *parser, ValueType *typ);
	/* some basic types */
	static int pointerAlignBytes;
	static int intAlignBytes;
private:
    /* add a new type to the set of types we know about */
    static ValueType *TypeAdd(Interpreter *pc, ParseState *parser,
                              ValueType *parentType, BaseType base, int arraySize,
                              const char *identifier, int sizeNeed, int alignBytes);
    /* add a base type */
    static void TypeAddBaseType(Interpreter *pc, ValueType *typeNode,
                                BaseType base, int sizeNeed, int alignBytes);
    /* deallocate heap-allocated types */
    static void TypeCleanupNode(Interpreter *pc, ValueType *typ);
    /* parse a struct or union declaration */
    static void TypeParseStruct(ParseState *parser, ValueType **typ,
                                int isStruct);
    /* parse an enum declaration */
    static void TypeParseEnum(ParseState *parser, ValueType **typ);
    /* parse a type - the part at the end after the identifier. eg.
    array specifications etc. */
    static ValueType *TypeParseBack(Interpreter *pc, ParseState *parser,
                                    ValueType *fromType);

};
#endif //TYPE_H
